package utility;

public class Ioz{

// Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
//   This program is free software; you can redistribute it and/or modify
//   it under the terms of the GNU General Public License as published by
//   the Free Software Foundation; either version 2, or (at your option)
//   any later version.
//
//   This program is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   GNU General Public License for more details.
//***********************************************************************/
//

//  An IO layer to support transparent compression/uncompression.
//  (Currently only "required" functionality is supported.)
//
//  There are various reasons for making this a full-blown module
//  instead of just defining a few macros:
//  
//  - Ability to switch between compressed and uncompressed at run-time
//    (zlib with compression level 0 saves uncompressed, but still with
//    gzip header, so non-zlib server cannot read the savefile).
//    
//  - Flexibility to add other methods if desired (eg, bzip2, arbitrary
//    external filter program, etc).
//
//  FIXME: when zlib support _not_ included, should sanity check whether
//  the first few bytes are gzip marker and complain if so.
//**********************************************************************/
//
//#ifdef HAVE_CONFIG_H
//#include <config.h>
//#endif
//
//#include <errno.h>
//#include <stdarg.h>
//#include <stdio.h>
//#include <string.h>
//
//#ifdef HAVE_LIBZ
//#include <zlib.h>
//#endif
//
//#include "log.h"
//#include "mem.h"
//#include "shared.h"
//#include "support.h"
//
//#include "ioz.h"
//
//struct fz_FILE_s {
//  enum fz_method method;
//  union {
//    FILE *plain;		/* FZ_PLAIN */
//#ifdef HAVE_LIBZ
//    gzFile zlib;		/* FZ_ZLIB */
//#endif
//  } u;
//};
//
///***************************************************************
//  Open file for reading/writing, like fopen.
//  Parameters compress_method and compress_level only apply
//  for writing: for reading try to use the most appropriate
//  available method.
//  Returns null if there was a problem; check errno for details.
//  (If errno is 0, and using FZ_ZLIB, probably had zlib error
//  Z_MEM_ERROR.  Wishlist: better interface for errors?)
//***************************************************************/
//fz_FILE *fz_from_file(final String filename, final String in_mode,
//		      enum fz_method method, int compress_level)
//{
//  fz_FILE *fp;
//  char mode[64];
//
//  if (!is_reg_file_for_access(filename, in_mode[0] == 'w')) {
//    return null;
//  }
//
//  fp = (fz_FILE *)fc_malloc(sizeof(*fp));
//  mode = in_mode;
//
//  if (mode[0] == 'w') {
//    /* Writing: */
//    if (compress_level == 0) {
//      method = FZ_PLAIN;
//    }
//#ifndef HAVE_LIBZ
//    /* In theory this shouldn't happen, but check anyway. */
//    if (method == FZ_ZLIB) {
//      util.freelog(Log.LOG_NORMAL, "Not compiled with zlib support, reverting to plain.");
//      method = FZ_PLAIN;
//    }
//#endif
//  } else {
//    /* Reading: ignore specified method and try best: */
//#ifdef HAVE_LIBZ
//    method = FZ_ZLIB;
//#else
//    method = FZ_PLAIN;
//#endif
//  }
//
//  fp.method = method;
//
//  switch (fp.method) {
//#ifdef HAVE_LIBZ
//  case FZ_ZLIB:
//    /*  gz files are binary files, so we should add "b" to mode! */
//    sz_strlcat(mode,"b");
//    if (mode[0] == 'w') {
//      cat_snprintf(mode, sizeof(mode), "%d", compress_level);
//    }
//    fp.u.zlib = gzopen(filename, mode);
//    if (!fp.u.zlib) {
//      free(fp);
//      fp = null;
//    }
//    break;
//#endif
//  case FZ_PLAIN:
//    fp.u.plain = fopen(filename, mode);
//    if (!fp.u.plain) {
//      free(fp);
//      fp = null;
//    }
//    break;
//  default:
//    /* Should never happen */
//    util.die("Internal error: Bad fz_fromFile method: %d", fp.method);
//  }
//  return fp;
//}
//
///***************************************************************
//  Open uncompressed stream for reading/writing.
//***************************************************************/
//fz_FILE *fz_from_stream(FILE *stream)
//{
//  fz_FILE *fp;
//
//  if (!stream) {
//    return null;
//  }
//
//  fp = fc_malloc(sizeof(*fp));
//  fp.method = FZ_PLAIN;
//  fp.u.plain = stream;
//  return fp;
//}
//
///***************************************************************
//  Close file, like fclose.
//  Returns 0 on success, or non-zero for problems (but don't call
//  fz_ferror in that case because the struct has already been
//  free'd;  wishlist: better interface for errors?)
//  (For FZ_PLAIN returns EOF and could check errno;
//  for FZ_ZLIB: returns zlib error number; see zlib.h.)
//***************************************************************/
//int fz_fclose(fz_FILE *fp)
//{
//  int retval = 0;
//  
//  switch(fp.method) {
//#ifdef HAVE_LIBZ
//  case FZ_ZLIB:
//    retval = gzclose(fp.u.zlib);
//    if (retval > 0) {
//      retval = 0;		/* only negative Z values are errors */
//    }
//    break;
//#endif
//  case FZ_PLAIN:
//    retval = fclose(fp.u.plain);
//    break;
//  default:
//    /* Should never happen */
//    util.die("Internal error: Bad fz_fclose method: %d", fp.method);
//  }
//  free(fp);
//  return retval;
//}
//
///***************************************************************
//  Get a line, like fgets.
//  Returns null in case of error, or when end-of-file reached
//  and no characters have been read.
//***************************************************************/
//char *fz_fgets(char *buffer, int size, fz_FILE *fp)
//{
//  char *retval = 0;
//  
//  switch(fp.method) {
//#ifdef HAVE_LIBZ
//  case FZ_ZLIB:
//    retval = gzgets(fp.u.zlib, buffer, size);
//    break;
//#endif
//  case FZ_PLAIN:
//    retval = fgets(buffer, size, fp.u.plain);
//    break;
//  default:
//    /* Should never happen */
//    util.die("Internal error: Bad fz_fgets method: %d", fp.method);
//  }
//  return retval;
//}
//
///***************************************************************
//  Print formated, like fprintf.
//  
//  Note: zlib doesn't have gzvfprintf, but thats ok because its
//  fprintf only does similar to what we do here (print to fixed
//  buffer), and in addition this way we get to use our safe
//  snprintf.
//
//  Returns number of (uncompressed) bytes actually written, or
//  0 on error.
//***************************************************************/
//int fz_fprintf(fz_FILE *fp, final String format)
//{
//  va_list ap;
//  int retval = 0;
//  
//  va_start(ap, format);
//  
//  switch(fp.method) {
//#ifdef HAVE_LIBZ
//  case FZ_ZLIB:
//    {
//      char buffer[4096];
//      int num;
//      num = my_vsnprintf(buffer, sizeof(buffer), format, ap);
//      if (num == -1) {
//	  util.freelog(Log.LOG_ERROR, "Too much data: truncated in fz_fprintf (%lu)",
//		  (unsigned long) sizeof(buffer));
//      }
//      retval = gzwrite(fp.u.zlib, buffer, (unsigned int)buffer.length());
//    }
//    break;
//#endif
//  case FZ_PLAIN:
//    retval = vfprintf(fp.u.plain, format, ap);
//    break;
//  default:
//    /* Should never happen */
//    util.die("Internal error: Bad fz_fprintf method: %d", fp.method);
//  }
//  va_end(ap);
//  return retval;
//}
//
///***************************************************************
//  Return non-zero if there is an error status associated with
//  this stream.  Check fz_strerror for details.
//***************************************************************/
//int fz_ferror(fz_FILE *fp)
//{
//  int retval = 0;
//  
//  switch(fp.method) {
//#ifdef HAVE_LIBZ
//  case FZ_ZLIB:
//    () gzerror(fp.u.zlib, &retval);	/* ignore string result here */
//    if (retval > 0) {
//      retval = 0;		/* only negative Z values are errors */
//    }
//    break;
//#endif
//  case FZ_PLAIN:
//    retval = ferror(fp.u.plain);
//    break;
//  default:
//    /* Should never happen */
//    util.die("Internal error: Bad fz_ferror method: %d", fp.method);
//  }
//  return retval;
//}
//
///***************************************************************
//  Return string (pointer to static memory) containing an error
//  description associated with the file.  Should only call
//  this is you know there is an error (eg, from fz_ferror()).
//  Note the error string may be based on errno, so should call
//  this immediately after problem, or possibly something else
//  might overwrite errno.
//***************************************************************/
//final String fz_strerror(fz_FILE *fp)
//{
//  final String retval = 0;
//  
//  switch(fp.method) {
//#ifdef HAVE_LIBZ
//  case FZ_ZLIB:
//    {
//      int errnum;
//      final String estr = gzerror(fp.u.zlib, &errnum);
//      if (errnum == Z_ERRNO) {
//	retval = mystrerror();
//      } else {
//	retval = estr;
//      }
//    }
//    break;
//#endif
//  case FZ_PLAIN:
//    retval = mystrerror();
//    break;
//  default:
//    /* Should never happen */
//    util.die("Internal error: Bad fz_strerror method: %d", fp.method);
//  }
//  return retval;
//}
}